#include "object_co_json_demo.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "util/hex_util.h"

// 定义对象描述
ST_OBJ_DESC_TYPE(s_hobby)
ST_OBJ_DESC_DEF_VAR(s_hobby, id, E_OFT_INT32)
ST_OBJ_DESC_JSON_DEF_VAR(s_hobby, name, E_OFT_STRING, hobby_name)
ST_OBJ_DESC_JSON_END(s_hobby)

ST_OBJ_DESC_TYPE(s_hobby_list)
ST_OBJ_DESC_JSON_DEF_VAR(s_hobby_list, count, E_OFT_INT32, -)
ST_OBJ_DESC_DEF_OBJS_HEAP(s_hobby_list, hobby_list, count, s_hobby)
ST_OBJ_DESC_JSON_END(s_hobby_list)

ST_OBJ_DESC_TYPE(s_student)
ST_OBJ_DESC_DEF_VAR(s_student, name, E_OFT_STRING)
ST_OBJ_DESC_DEF_VAR(s_student, rank, E_OFT_INT32)
ST_OBJ_DESC_DEF_VARS_STACK(s_student, hobby_arr, int32_t, E_OFT_INT32)
ST_OBJ_DESC_JSON_END(s_student)

ST_OBJ_DESC_TYPE(s_class)
ST_OBJ_DESC_DEF_VAR(s_class, class_name, E_OFT_STRING)
ST_OBJ_DESC_DEF_VAR(s_class, student_size, E_OFT_UINT16)
ST_OBJ_DESC_DEF_OBJS_HEAP(s_class, student_list, student_size, s_student)
ST_OBJ_DESC_JSON_END(s_class)

ST_OBJ_DESC_TYPE(s_school)
ST_OBJ_DESC_DEF_VAR(s_school, school_name, E_OFT_STRING)
ST_OBJ_DESC_DEF_VAR(s_school, class_count, E_OFT_UINT8)
ST_OBJ_DESC_DEF_OBJS_HEAP(s_school, class_list, class_count, s_class)
ST_OBJ_DESC_JSON_END(s_school)

ST_OBJ_DESC_TYPE(msg_head)
ST_OBJ_DESC_DEF_VAR(msg_head, code, E_OFT_INT32)
ST_OBJ_DESC_DEF_VAR(msg_head, id, E_OFT_INT32)
ST_OBJ_DESC_JSON_END(msg_head)

ST_OBJ_DESC_TYPE(msg_login_req)
ST_OBJ_DESC_DEF_OBJ(msg_login_req, head, msg_head)
ST_OBJ_DESC_DEF_VAR(msg_login_req, name, E_OFT_STRING)
ST_OBJ_DESC_DEF_VAR(msg_login_req, password, E_OFT_STRING)
ST_OBJ_DESC_JSON_END(msg_login_req)

ST_OBJ_DESC_TYPE(msg_login_res)
ST_OBJ_DESC_JSON_DEF_OBJ_EXPAND(msg_login_req, head, msg_head, head2)
ST_OBJ_DESC_DEF_VAR(msg_login_res, token, E_OFT_STRING)
ST_OBJ_DESC_JSON_END(msg_login_res)

int test_object_co_json(void)
{
    char hex[1024] = { 0x00 };
    uint32_t hex_len = 1024;

    s_hobby_list hobby_list1;
    memset(&hobby_list1, 0, sizeof(s_hobby_list));
    hobby_list1.count = 3;
    hobby_list1.hobby_list = malloc(sizeof(s_hobby)*3);

    memset(hobby_list1.hobby_list, 0, sizeof(s_hobby)*3);
    hobby_list1.hobby_list[0].id = 1;
    strcpy(hobby_list1.hobby_list[0].name,"篮球");
    hobby_list1.hobby_list[1].id = 2;
    strcpy(hobby_list1.hobby_list[1].name ,"足球");
    hobby_list1.hobby_list[2].id = 3;
    strcpy(hobby_list1.hobby_list[2].name ,"乒乓球");
    printf("hobby_list1.count = %d\n", hobby_list1.count);
    printf("hobby_list1.hobby_list1[0].id = %d\n", hobby_list1.hobby_list[0].id);
    printf("hobby_list1.hobby_list1[0].name = %s\n", hobby_list1.hobby_list[0].name);
    printf("hobby_list1.hobby_list1[1].id = %d\n", hobby_list1.hobby_list[1].id);
    printf("hobby_list1.hobby_list1[1].name = %s\n", hobby_list1.hobby_list[1].name);
    printf("hobby_list1.hobby_list1[2].id = %d\n", hobby_list1.hobby_list[2].id);
    printf("hobby_list1.hobby_list1[2].name = %s\n", hobby_list1.hobby_list[2].name);

    char json_buf[1024] = {0};  
    uint64_t buf_size = sizeof(json_buf);

    int ret = o2j_s_hobby_list(&hobby_list1, json_buf, buf_size);
    if (ret < 0) {
        printf("o2j_s_hobby_list error, ret = %d\n", ret);
        return -1;
    }    
    else {
        printf("o2j_s_hobby_list ok, ret = %d\n", ret);
    } 
   
    printf("json_buf = %s\n", json_buf);

    s_hobby_list hobby_list2;
    memset(&hobby_list2, 0, sizeof(s_hobby_list));
    ret = j2o_s_hobby_list(json_buf, strlen(json_buf), &hobby_list2);
    if (ret < 0) {
        printf("j2o_s_hobby_list error, ret = %d\n", ret);
        return -1;
    }
    else {
        printf("j2o_s_hobby_list ok, ret = %d\n", ret);
    }

    printf("hobby_list2.count = %d\n", hobby_list2.count);
    printf("hobby_list2.hobby_list1[0].id = %d\n", hobby_list2.hobby_list[0].id);
    printf("hobby_list2.hobby_list1[0].name = %s\n", hobby_list2.hobby_list[0].name);
    printf("hobby_list2.hobby_list1[1].id = %d\n", hobby_list2.hobby_list[1].id);
    printf("hobby_list2.hobby_list1[1].name = %s\n", hobby_list2.hobby_list[1].name);
    printf("hobby_list2.hobby_list1[2].id = %d\n", hobby_list2.hobby_list[2].id);
    printf("hobby_list2.hobby_list1[2].name = %s\n", hobby_list2.hobby_list[2].name);

    // memset(hex, 0, sizeof(hex));
    // encode_hex((uint8_t *)hobby_list1.hobby_list, hobby_list1.count*sizeof(s_hobby), hex, &hex_len, 0);
    // printf("hobby_list1 = %s\n", hex);
    // memset(hex, 0, sizeof(hex));
    // encode_hex((uint8_t *)hobby_list2.hobby_list, hobby_list2.count*sizeof(s_hobby), hex, &hex_len, 0);
    // printf("hobby_list2 = %s\n", hex);

    assert(hobby_list1.count == hobby_list2.count);
    assert(0 == memcmp(hobby_list1.hobby_list, hobby_list2.hobby_list, hobby_list1.count*sizeof(s_hobby)));

    obj_free_s_hobby_list(&hobby_list1);
    obj_free_s_hobby_list(&hobby_list2);

    s_student student1;
    memset(&student1, 0, sizeof(s_student));
    strcpy(student1.name, "张三");
    student1.rank = 1;
    student1.hobby_arr[0] = 2;
    student1.hobby_arr[1] = 3;
    memset(json_buf,0, sizeof(json_buf));
    buf_size = sizeof(json_buf);
    ret = o2j_s_student(&student1, json_buf, buf_size);
    if (ret < 0) {
        printf("%s:%d o2j_s_student error, ret = %d\n", __func__, __LINE__, ret);
        return -1;
    }    
    else {
        printf("o2j_s_student ok, ret = %d\n", ret);
    }
    printf("s_student json_buf = %s\n", json_buf);

    s_student student2;
    ret = j2o_s_student(json_buf, strlen(json_buf), &student2);
    if (ret < 0) {
        printf("%s:%d j2o_s_student error, ret = %d\n",  __func__, __LINE__, ret);
        return -1;
    }
    else {
        printf("j2o_s_student ok, ret = %d\n", ret);
    }
    printf("student2.name = %s\n", student2.name);
    printf("student2.rank = %d\n", student2.rank);
    printf("student2.hobby_arr[0] = %d\n", student2.hobby_arr[0]);
    printf("student2.hobby_arr[1] = %d\n", student2.hobby_arr[1]);

    assert(0 == strcmp(student1.name, student2.name));
    assert(student1.rank == student2.rank);
    assert(student1.hobby_arr[0] == student2.hobby_arr[0]);
    assert(student1.hobby_arr[1] == student2.hobby_arr[1]);

    obj_free_s_student(&student1);
    obj_free_s_student(&student2);
    
    s_school school1;
    s_school school2;
    memset(&school1, 0, sizeof(s_school));
    memset(&school2, 0, sizeof(s_school));
    strcpy(school1.school_name, "北京大学");
    school1.class_count = 5;
    school1.class_list = malloc(school1.class_count * sizeof(s_class));
    memset(school1.class_list, 0, school1.class_count * sizeof(s_class));
    strcpy(school1.class_list[0].class_name, "一班");
    school1.class_list[0].student_size = 3;
    school1.class_list[0].student_list = malloc(school1.class_list[0].student_size * sizeof(s_student));
    memset(school1.class_list[0].student_list, 0, school1.class_list[0].student_size * sizeof(s_student));
    strcpy(school1.class_list[0].student_list[0].name ,"张三");
    school1.class_list[0].student_list[0].rank = 1;
    school1.class_list[0].student_list[0].hobby_arr[0] = 2;
    school1.class_list[0].student_list[0].hobby_arr[1] = 3;
    strcpy(school1.class_list[0].student_list[1].name , "李四");
    school1.class_list[0].student_list[1].rank = 2;
    school1.class_list[0].student_list[1].hobby_arr[0] = 4;
    school1.class_list[0].student_list[1].hobby_arr[1] = 5;
    strcpy(school1.class_list[0].student_list[2].name , "王五");
    school1.class_list[0].student_list[2].rank = 3;
    school1.class_list[0].student_list[2].hobby_arr[0] = 6;
    school1.class_list[0].student_list[2].hobby_arr[1] = 7;
    strcpy(school1.class_list[1].class_name, "二班");
    school1.class_list[1].student_size = 3;
    school1.class_list[1].student_list = malloc(school1.class_list[1].student_size * sizeof(s_student));
    memset(school1.class_list[1].student_list, 0, school1.class_list[1].student_size * sizeof(s_student));
    strcpy(school1.class_list[1].student_list[0].name , "赵六");
    school1.class_list[1].student_list[0].rank = 1;
    school1.class_list[1].student_list[0].hobby_arr[0] = 8;
    school1.class_list[1].student_list[0].hobby_arr[1] = 9;
    strcpy(school1.class_list[1].student_list[1].name ,"钱七");
    school1.class_list[1].student_list[1].rank = 2;
    school1.class_list[1].student_list[1].hobby_arr[0] = 10;
    school1.class_list[1].student_list[1].hobby_arr[1] = 11;
    strcpy(school1.class_list[1].student_list[2].name ,"孙八");
    school1.class_list[1].student_list[2].rank = 3; 
    school1.class_list[1].student_list[2].hobby_arr[0] = 12;    
    school1.class_list[1].student_list[2].hobby_arr[1] = 13;
    strcpy(school1.class_list[2].class_name, "三班");
    school1.class_list[2].student_size = 2;
    school1.class_list[2].student_list = malloc(school1.class_list[2].student_size * sizeof(s_student));
    memset(school1.class_list[2].student_list, 0, school1.class_list[2].student_size * sizeof(s_student));
    strcpy(school1.class_list[2].student_list[0].name ,  "周九");
    school1.class_list[2].student_list[0].rank = 1;
    school1.class_list[2].student_list[0].hobby_arr[0] = 14;
    school1.class_list[2].student_list[0].hobby_arr[1] = 15;
    strcpy(school1.class_list[2].student_list[1].name , "吴十");
    school1.class_list[2].student_list[1].rank = 2; 
    school1.class_list[2].student_list[1].hobby_arr[0] = 16;    
    school1.class_list[2].student_list[1].hobby_arr[1] = 17;
     strcpy(school1.class_list[3].class_name, "4班");
    school1.class_list[3].student_size = 0;
    school1.class_list[4].student_size = 1;
    school1.class_list[4].student_list = malloc(school1.class_list[4].student_size * sizeof(s_student));
    memset(school1.class_list[4].student_list, 0, school1.class_list[4].student_size * sizeof(s_student));
    strcpy(school1.class_list[4].student_list[0].name ,  "周九");
    school1.class_list[4].student_list[0].rank = 103;
    school1.class_list[4].student_list[0].hobby_arr[0] = 22;
    school1.class_list[4].student_list[0].hobby_arr[1] = 23;

    buf_size = sizeof(json_buf);
    memset(json_buf, 0, buf_size);
    ret = o2j_s_school(&school1, json_buf, buf_size);
    if (ret < 0)
    {
        printf("%s:%d o2j_s_school error, ret = %d\n",  __func__, __LINE__, ret);
        return -1;
    }

    printf("s_school json_buf = %s\n", json_buf);

    ret = j2o_s_school(json_buf, strlen(json_buf), &school2);
    if (ret < 0)
    {
        printf("j2o_s_school error, ret = %d\n", ret);
        return -1;
    }
    printf("school2.class_list[0].class_name = %s\n", school2.class_list[0].class_name);
    printf("school2.class_list[1].class_name = %s\n", school2.class_list[1].class_name);
    printf("school2.class_list[2].class_name = %s\n", school2.class_list[2].class_name);
    printf("school2.class_list[3].class_name = %s\n", school2.class_list[3].class_name);
    printf("school2.class_list[4].class_name = %s\n", school2.class_list[4].class_name);
    printf("school2.class_list[0].student_size = %d\n", school2.class_list[0].student_size);
    printf("school2.class_list[1].student_size = %d\n", school2.class_list[1].student_size);    
    printf("school2.class_list[4].student_list[0].hobby_arr[1] = %d\n", school2.class_list[4].student_list[0].hobby_arr[1]);    
    assert(0 == memcmp(school1.school_name, school2.school_name, sizeof(school1.school_name)));
    assert(school1.class_count == school2.class_count);

    assert(0 == memcmp(school1.class_list[0].class_name, school2.class_list[0].class_name, sizeof(school1.class_list[0].class_name)));
    assert(0 == memcmp(school1.class_list[1].class_name, school2.class_list[1].class_name, sizeof(school1.class_list[1].class_name)));
    assert(0 == memcmp(school1.class_list[2].class_name, school2.class_list[2].class_name, sizeof(school1.class_list[2].class_name)));
    assert(0 == memcmp(school1.class_list[3].class_name, school2.class_list[3].class_name, sizeof(school1.class_list[3].class_name)));
    assert(0 == memcmp(school1.class_list[4].class_name, school2.class_list[4].class_name, sizeof(school1.class_list[4].class_name)));
    assert(0 == memcmp(school1.class_list[0].student_list, school2.class_list[0].student_list, sizeof(s_student)*school2.class_list[0].student_size));
    assert(0 == memcmp(school1.class_list[0].student_list[0].name, school2.class_list[0].student_list[0].name, sizeof(school1.class_list[0].student_list[0].name)));
    assert(0 == memcmp(school1.class_list[4].student_list[0].name, school2.class_list[4].student_list[0].name, sizeof(school1.class_list[4].student_list[0].name)));
    assert(school1.class_list[4].student_list[0].rank == school2.class_list[4].student_list[0].rank);
    assert(school1.class_list[4].student_list[0].hobby_arr[0] == school2.class_list[4].student_list[0].hobby_arr[0]);
    assert(school1.class_list[4].student_list[0].hobby_arr[1] == school2.class_list[4].student_list[0].hobby_arr[1]);

    obj_free_s_school(&school1);
    obj_free_s_school(&school2);


    msg_login_req login_req1;
    msg_login_req login_req2;
    memset(&login_req1, 0, sizeof(login_req1));
    memset(&login_req2, 0, sizeof(login_req2));
    login_req1.head.code = 1001;
    login_req1.head.id = 1;
    strcpy(login_req1.name, "admin");
    strcpy(login_req1.password, "123456");

    buf_size = sizeof(json_buf);
    memset(json_buf, 0, buf_size);
    ret = o2j_msg_login_req(&login_req1, json_buf, buf_size);
    if (ret < 0)
    {
        printf("%s:%d o2j_msg_login_req error, ret = %d\n",  __func__, __LINE__, ret);
        return -1;
    }

    printf("login_req1 json_buf = %s\n", json_buf);
    ret = j2o_msg_login_req(json_buf, strlen(json_buf), &login_req2);
    if (ret < 0)
    {
        printf("j2o_msg_login_req error, ret = %d\n", ret);
        return -1;
    }
    printf("login_req2.head.code = %d\n", login_req2.head.code);
    printf("login_req2.head.id = %d\n", login_req2.head.id);
    printf("login_req2.name = %s\n", login_req2.name);
    printf("login_req2.password = %s\n", login_req2.password);

    assert(login_req2.head.code == login_req1.head.code);
    assert(login_req2.head.id == login_req1.head.id);
    assert(0 == memcmp(login_req1.name, login_req2.name, sizeof(login_req1.name)));
    assert(0 == memcmp(login_req1.password, login_req2.password, sizeof(login_req1.password)));

    msg_login_res login_res1;
    msg_login_res login_res2;
    memset(&login_res1, 0, sizeof(login_res1));
    memset(&login_res2, 0, sizeof(login_res2));
    login_res1.head.code = 1002;
    login_res1.head.id = 10002;
    strcpy(login_res1.token, "1234567890"); 

    buf_size = sizeof(json_buf);
    memset(json_buf, 0, buf_size);
    ret = o2j_msg_login_res(&login_res1, json_buf, buf_size);
    if (ret < 0)
    {
        printf("%s:%d o2j_msg_login_res error, ret = %d\n",  __func__, __LINE__, ret);
        return -1;
    }

    printf("login_res1 json_buf = %s\n", json_buf);
    ret = j2o_msg_login_res(json_buf, strlen(json_buf), &login_res2);
    if (ret < 0)
    {
        printf("j2o_msg_login_req error, ret = %d\n", ret);
        return -1;
    }

    printf("login_res2.head.code = %d\n", login_res2.head.code);
    printf("login_res2.head.id = %d\n", login_res2.head.id);
    printf("login_res2.token = %s\n", login_res2.token);

    assert(login_res2.head.code == login_res1.head.code);
    assert(login_res2.head.id == login_res1.head.id);
    assert(0 == memcmp(login_res1.token, login_res2.token, sizeof(login_res2.token)));
    return 0;
}   

int main(int argc, char **argv)
{
    test_object_co_json();
    return 0;
}